from rest_framework.permissions import BasePermission, DjangoModelPermissions, IsAuthenticated
from django.utils import timezone
from django.db import models
import logging
from .decorators import has_permission

logger = logging.getLogger(__name__)


class ExtendedModelPermissions(DjangoModelPermissions):
    """
    扩展的模型权限类 - 支持权限扩展和角色系统

    特性:
    1. 支持权限扩展 (PermissionExtension)
    2. 支持角色系统 (UserRoleAssignment)
    3. 支持权限状态检查 (status='active')
    4. 支持角色过期时间检查
    5. 兼容Django原生权限系统
    """
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        'OPTIONS': [],
        'HEAD': [],
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }

    def has_permission(self, request, view):
        """检查用户是否有访问权限"""
        # 超级用户拥有所有权限
        if request.user.is_superuser:
            return True

        # 未认证用户无权限
        if not request.user.is_authenticated:
            return False

        # 获取所需权限
        required_perms = self.get_required_permissions(request.method, view.get_queryset().model)

        # 检查用户是否有所需权限
        return self.user_has_permissions(request.user, required_perms, view)

    def user_has_permissions(self, user, required_perms, view):
        """检查用户是否有所需权限（支持权限扩展和角色）"""
        if not required_perms:
            return True

        # 获取用户的所有有效权限
        user_permissions = self.get_user_extended_permissions(user)

        # 检查是否有所需权限
        for perm in required_perms:
            if perm not in user_permissions:
                logger.warning(f"用户 {user.username} 缺少权限: {perm}")
                return False
        return True

    def get_user_extended_permissions(self, user):
        """获取用户的所有有效权限（包括直接分配和角色分配）"""
        permissions = set()

        try:
            # 1. 获取用户直接分配的权限
            user_permissions = user.user_permissions.filter(
                permissionextension__status='active'
            ).values_list('content_type__app_label', 'codename')

            for app_label, codename in user_permissions:
                permissions.add(f'{app_label}.{codename}')

            # 2. 获取通过角色分配的权限
            from apps.permissions.models import UserRoleAssignment

            active_assignments = UserRoleAssignment.objects.filter(
                user=user,
                status='active'
            ).filter(
                # 检查过期时间
                models.Q(expires_at__isnull=True) | models.Q(expires_at__gt=timezone.now())
            ).select_related('role__group')

            for assignment in active_assignments:
                role_permissions = assignment.role.group.permissions.filter(
                    permissionextension__status='active'
                ).values_list('content_type__app_label', 'codename')

                for app_label, codename in role_permissions:
                    permissions.add(f'{app_label}.{codename}')

        except Exception as e:
            logger.error(f"获取用户权限失败: {e}")
            # 如果权限扩展系统不可用，回退到Django原生权限
            return set(user.get_all_permissions())

        return permissions

    def has_object_permission(self, request, view, obj):
        """对象级权限检查"""
        # 超级用户拥有所有权限
        if request.user.is_superuser:
            return True

        return super().has_object_permission(request, view, obj)

   
 

    def check_permission(self, user, required_perm):
        """检查用户是否有指定权限"""
        if required_perm is None:
            # 只需要认证
            return user.is_authenticated

        # 检查特定权限
        user_permissions = self.get_user_extended_permissions(user)
        has_perm = required_perm in user_permissions

        if not has_perm:
            logger.warning(f"用户 {user.username} 缺少权限: {required_perm}")

        return has_perm


class SelfCreatePermission(ExtendedModelPermissions):
    """自动对应当前应用模型的Create权限"""

    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        if request.user.is_superuser:
            return True

        # 获取当前模型的add权限
        model = view.get_queryset().model
        app_label = model._meta.app_label
        model_name = model._meta.model_name
        required_perm = f'{app_label}.add_{model_name}'

        user_permissions = self.get_user_extended_permissions(request.user)
        return required_perm in user_permissions


class SelfReadPermission(ExtendedModelPermissions):
    """自动对应当前应用模型的Read权限"""

    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        if request.user.is_superuser:
            return True

        # 获取当前模型的view权限
        model = view.get_queryset().model
        app_label = model._meta.app_label
        model_name = model._meta.model_name
        required_perm = f'{app_label}.view_{model_name}'

        user_permissions = self.get_user_extended_permissions(request.user)
        return required_perm in user_permissions


class SelfUpdatePermission(ExtendedModelPermissions):
    """自动对应当前应用模型的Update权限"""

    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        if request.user.is_superuser:
            return True

        # 获取当前模型的change权限
        model = view.get_queryset().model
        app_label = model._meta.app_label
        model_name = model._meta.model_name
        required_perm = f'{app_label}.change_{model_name}'

        user_permissions = self.get_user_extended_permissions(request.user)
        return required_perm in user_permissions


class SelfDestroyPermission(ExtendedModelPermissions):
    """自动对应当前应用模型的Destroy权限"""

    def has_permission(self, request, view):
        if not request.user.is_authenticated:
            return False
        if request.user.is_superuser:
            return True

        # 获取当前模型的delete权限
        model = view.get_queryset().model
        app_label = model._meta.app_label
        model_name = model._meta.model_name
        required_perm = f'{app_label}.delete_{model_name}'

        user_permissions = self.get_user_extended_permissions(request.user)
        return required_perm in user_permissions

 